package com.mango.module.ldap;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import com.mango.module.base.config.PipelineConfig;
import com.mango.module.base.config.SpringContextUtils;
import com.mango.module.ldap.domain.DepartDO;
import com.mango.module.ldap.domain.PersonDO;

import lombok.extern.slf4j.Slf4j;
 
/**
 * LDAP传统工具
 * @author Mango-Lab
 * @Date 2021年4月8日
 */
@Slf4j
public class LdapUtil {	
	
	/**
	 * 获取ldap认证
	 * @param url
	 * @param basedn
	 * @param root
	 * @param pwd
	 * @return
	 */
	private static LdapContext ldapConnect(){
		PipelineConfig pConfig=SpringContextUtils.getBean(PipelineConfig.class);
		String url = pConfig.getLdapurls();
		String root = pConfig.getLdapusername();  // 用户
		String pwd =pConfig.getLdappassword();  // pwd
		String factory = "com.sun.jndi.ldap.LdapCtxFactory";
		String simple="simple";
		Hashtable<String, String> env = new Hashtable<String, String>();
		env.put(Context.INITIAL_CONTEXT_FACTORY,factory);
		env.put(Context.PROVIDER_URL, url);
		env.put(Context.SECURITY_AUTHENTICATION, simple);
		env.put(Context.SECURITY_PRINCIPAL, root);
		env.put(Context.SECURITY_CREDENTIALS, pwd);
		LdapContext ctx = null;
		Control[] connCtls = null;
		try {
			ctx = new InitialLdapContext(env, connCtls);
			log.info( "认证成功:"+url); 
		}catch (javax.naming.AuthenticationException e) {
			log.error("认证失败：",e);
        } catch (Exception e) {
        	log.error("认证出错：",e);
        }
		return ctx;
	}
   
    /**
     * 获取用户信息
     * @param ctx
     * @param basedn
     * @return
     */
    public static List<PersonDO> readLdap(String basedn){
		
		List<PersonDO> lm=new ArrayList<PersonDO>();
		try {
			LdapContext ctx=ldapConnect();
			if(ctx==null) {
				log.info("连接不存在！");
				return lm;
			}
				//过滤条件
	            String filter = "(&(objectClass=*)(uid=*))";
				String[] attrPersonArray = {"dn", "cn", "sn", "uid",  "givenName", "lastTime", "roleId", "roleName", "status", "zjhm", "userPassword", "ou" };
				//搜索控件
				SearchControls searchControls = new SearchControls();
	            /**
	             * 搜索范围
	             * OBJECT_SCOPE、ONELEVEL_SCOPE、SUBTREE_SCOPE
	             * 对象范围、一级范围、子树范围
	             */
	            searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
	            searchControls.setReturningAttributes(attrPersonArray);
	            //1.要搜索的上下文或对象的名称；2.过滤条件，可为null，默认搜索所有信息；3.搜索控件，可为null，使用默认的搜索控件
	            NamingEnumeration<SearchResult> answer = ctx.search(basedn, filter.toString(),searchControls);
	            while (answer.hasMore()) {
	                SearchResult result = (SearchResult) answer.next();
	                NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
	                PersonDO lu=new PersonDO();
	                while (attrs.hasMore()) {
	                    Attribute attr = (Attribute) attrs.next();
	                    Object value = attr.get();
	                    switch (attr.getID()) {
						case "userPassword":
	                    	lu.setUserPassword(new String((byte [])value));
							break;
						case "uid":
	                    	lu.setUserId(value==null?"":value.toString());
							break;
						case "givenName":
	                    	lu.setGivenName(value==null?"":value.toString());
							break;
						case "cn":
	                    	lu.setName(value==null?"":value.toString());
							break;
						case "sn":
	                    	lu.setSn(value==null?"":value.toString());
							break;
						case "lastTime":
	                    	lu.setLastTime(value==null?"":value.toString());
							break;
						case "roleId":
	                    	lu.setRoleId(value==null?"":value.toString());
							break;
						case "roleName":
	                    	lu.setRoleName(value==null?"":value.toString());
							break;
						case "status":
	                    	lu.setStatus(value==null?"":value.toString());
							break;
						case "zjhm":
	                    	lu.setZjhm(value==null?"":value.toString());
							break;
						default:
							break;
						}
	                    // 10 个属性
	                }
	                if(lu.getUserId()!=null)
                    	lm.add(lu);
	            }
		}catch (Exception e) {
			log.error("获取用户信息异常:",e);
		}
		return lm;
	}
    
    /**
     * 获取部门信息
     * @param ctx
     * @param basedn
     * @return
     */
    public static List<DepartDO> readGroup(String basedn){
		
		List<DepartDO> lm=new ArrayList<DepartDO>();
		try {
			LdapContext ctx=ldapConnect();
			if(ctx==null) {
				log.info("连接不存在！");
				return lm;
			}
				//过滤条件
	            String filter = "(&(objectClass=organizationalUnit))";
				String[] attrPersonArray = { "ou","description" };
				//搜索控件
				SearchControls searchControls = new SearchControls();
	            /**
	             * 搜索范围
	             * OBJECT_SCOPE、ONELEVEL_SCOPE、SUBTREE_SCOPE
	             * 对象范围、一级范围、子树范围
	             */
	            searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
	            searchControls.setReturningAttributes(attrPersonArray);
	            //1.要搜索的上下文或对象的名称；2.过滤条件，可为null，默认搜索所有信息；3.搜索控件，可为null，使用默认的搜索控件
	            NamingEnumeration<SearchResult> answer = ctx.search(basedn, filter.toString(),searchControls);
	            while (answer.hasMore()) {
	                SearchResult result = (SearchResult) answer.next();
	                NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
	                DepartDO depart=new DepartDO();
	                while (attrs.hasMore()) {
	                    Attribute attr = (Attribute) attrs.next();
	                    Object value = attr.get();
	                    System.out.println(value);
	                    switch (attr.getID()) {
						case "ou":
	                    	depart.setCode(value==null?"":value.toString());
							break;
						case "description":
	                    	depart.setDescription(value==null?"":value.toString());
							break;
						default:
							break;
						}
	                    // 12 个属性
	                }
	                if(depart.getCode()!=null)
                    	lm.add(depart);
	            }
		}catch (Exception e) {
			log.error("获取部门信息异常:",e);
		}
		return lm;
	}
 
    /**
     * string 转 数值
     * @param m
     * @return
     */
    public static String strToint(String m){
    	if(m==null || "".equals(m))
    		return "-1";
        char [] a=m.toCharArray();
        StringBuffer sbu = new StringBuffer();
        for(char c:a)
        	sbu.append((int)c);
        log.debug(sbu.toString());
        return sbu.toString();
    }
    /**
	 * 获取时间戳
	 * @return
	 */
	public static long getNowTimeStamp() {
        long time = System.currentTimeMillis();
        time =  time / 1000;
        return time;
    }	
}